home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1993…ch: Other People's Memory / ADC Developer CD (1993-03) (''Other People's Memory'')_iso / Dev.CD Mar 93.iso / Tools & Apps / Graphics & Imaging / Virtual Sphere 1.0 / VirtualSphere.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-14  |  3.7 KB  |  99 lines  |  [TEXT/MPS ]

  1. /*•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
  2. /* VirtualSphere.c
  3. /*
  4. /* Implements the Virtual Sphere algorithm for 3D rotation using a 2D input device.
  5. /* See paper "A Study in Interactive 3-D Rotation Using 2-D Control Devices" by
  6. /* Michael Chen, S. Joy Mountford and Abigail Sellen published in the ACM Siggraph '88
  7. /* proceedings (Volume 22, Number 4, August 1988) for more detail.  The code here
  8. /* provides a much simpler implementation than that described in the paper.
  9. /*
  10. /* Author: Michael Chen, Human Interface Group / ATG
  11. /* Copyright © 1987-92 Apple Computer, Inc.  All rights reserved.
  12. /*
  13. /* Part of Virtual Sphere Sample Code Release v1.0
  14. /*•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••*/
  15.  
  16. #ifndef    __VIRTUALSPHERE__
  17. #include "VirtualSphere.h"
  18. #endif
  19.  
  20. /* Local routine */
  21. static void PointOnUnitSphere (Point    p,
  22.                                Point    cueCenter,
  23.                                Integer    cueRadius,
  24.                                CPoint3D    *v);
  25.  
  26. /*=================================================================================================
  27. /* VirtualSphere
  28. /* 
  29. /* Determine the axis and angle of rotation from the last 2 locations of the mouse
  30. /* relative to the Virtual Sphere cue circle.  
  31. /*-------------------------------------------------------------------------------------------------*/
  32. pascal void VirtualSphere (Point    p,    
  33.                            Point    q,
  34.                            Point    cueCenter,
  35.                            Integer    cueRadius,
  36.                            CPoint3D    *axisOfRotation,
  37.                            Real        *angleOfRotation)
  38. {
  39.     CPoint3D        pp, qq;    
  40.     Real            axisLength;
  41.     
  42.     /* Project mouse points to 3D points on the +z hemisphere of a unit sphere. */
  43.     PointOnUnitSphere (p, cueCenter, cueRadius, &pp);
  44.     PointOnUnitSphere (q, cueCenter, cueRadius, &qq);
  45.  
  46.     /* Consider the 2 projected points as vectors from the center of the unit sphere.
  47.      * Compute the axis of rotation by cross product of these vectors. */
  48.     CrossProduct3D (&qq, &pp, axisOfRotation);
  49.     
  50.     /* The angle of rotation is determined from the length of the cross product. */
  51.     axisLength = Length3D (axisOfRotation);
  52.     *angleOfRotation = asin (axisLength);
  53.  
  54.     /* The axis of rotation must be a unit vector, so normalize it. */
  55.     if (*angleOfRotation > 0) {
  56.         axisOfRotation->x /= axisLength;
  57.         axisOfRotation->y /= axisLength;
  58.         axisOfRotation->z /= axisLength;
  59.     }
  60. }
  61.  
  62. /*=================================================================================================
  63. /* PointOnUnitSphere
  64. /*
  65. /* Project a 2D point on a circle to a 3D point on the +z hemisphere of a unit sphere.
  66. /* If the 2D point is outside the circle, it is first mapped to the nearest point on
  67. /* the circle before projection.
  68. /* Orthographic projection is used, though technically the field of view of the camera
  69. /* should be taken into account.  However, the discrepancy is neglegible.
  70. /*-------------------------------------------------------------------------------------------------*/
  71. static void PointOnUnitSphere (Point    p,
  72.                                Point    cueCenter,
  73.                                Integer    cueRadius,
  74.                                CPoint3D    *v)
  75. {
  76.     Real    length;
  77.     Real    lengthSqared;
  78.     
  79.     /* Turn the mouse points into vectors relative to the center of the circle
  80.      * and normalize them.  Note we need to flip the y value since the 3D coordinate
  81.      * has positive y going up. */
  82.     v->x = (Real)  (p.h - cueCenter.h) / (Real) cueRadius;
  83.     v->y = (Real) -(p.v - cueCenter.v) / (Real) cueRadius;
  84.  
  85.     lengthSqared = v->x*v->x + v->y*v->y;
  86.     
  87.     /* Project the point onto the sphere, assuming orthographic projection.
  88.      * Points beyond the virtual sphere are normalized onto 
  89.      * edge of the sphere (where z = 0). */
  90.     if (lengthSqared < 1.0) {
  91.         v->z = sqrt (1.0 - lengthSqared);
  92.     } else {
  93.         length = sqrt (lengthSqared);
  94.         v->x /= length;
  95.         v->y /= length;
  96.         v->z = 0.0;
  97.     }
  98. }
  99.